// 数组/元组重新构造
type tuple = [1,2,3]
type Push<Arr extends unknown[], Ele> = [...Arr, Ele]
type PushRes = Push<tuple, 4>

// 两个数组合并
type Zip2<arr1 extends unknown[], arr2 extends unknown[]> = arr1 extends [infer first1, ...infer other1] 
? arr2 extends [infer first2, ...infer other2] ? [[first1, first2], ...Zip2<other1, other2>] : []
: []

type zip = Zip2<[1,2,3], [2,3,4]>

/// 字符串重新构造
// 将下划线转大写字母
type CamelCase<Str extends string> = Str extends `${infer left}_${infer Right}${infer Reset}`
? `${left}${Uppercase<Right>}${CamelCase<Reset>}` 
: Str

type CamelCaseRes = CamelCase<'xie_xie_xie'>

//函数类型的重新构造
// 添加参数
type AppendArgument<Fun extends Function, Arg> = Fun extends (...arg: infer ArgType) => infer ReturnType ? (...agr: [...ArgType, Arg]) => ReturnType : never
type AppendArgumentRes = AppendArgument<(name: string) => string, number>
// 索引类型的重新构造
// 修改value
type Mapping<Obj extends Object> = {
  [key in keyof Obj]: [Obj[key], Obj[key]]
}
type MappingRes = Mapping<{name: 1}>
// 修改key
type UppercaseKey<Obj extends Record<string, any>> = {
  [key in keyof Obj as Uppercase<key & string>]: Obj[key]
}
type UppercaseKeyRes = UppercaseKey<{name: 1}>

// 添加只读
type ToReadonly<T> =  {
  readonly [Key in keyof T]: T[Key];
}
// 去只读
type ToMutable<T> = {
  -readonly [Key in keyof T]: T[Key]
}
// 添加可选
type ToPartial<T> = {
  [Key in keyof T]?: T[Key]
}
// 去可选
type ToRequired<T> = {
  [Key in keyof T]-?: T[Key]
}

// 根据类型值过滤
type FilterByValueType<Obj extends Record<string, any>, ValueType> = {
  [key in keyof Obj as Obj[key] extends ValueType ? key : never]: Obj[key]
}
type FilterByValueTypeRes = FilterByValueType<{name: number, sex: boolean}, boolean>